/**
 * GeoSOA/olap4js/MDXQuery.js
 *
 * MDXQuery object
 *
 * Copyright (C) 2010 Atol CD
 * See LICENSE file under this distribution for licensing information
 * 
 * @author Vincent Plantegenet
 * @since 201004
 **/
  
dojo.provide("AtolCD.olap4js.MDXQuery");

/**
* @param {Object} options The options
* @constructor
*/
AtolCD.olap4js.MDXQuery = function (options,solap) {
	
	this.MDXQuery = "";
	this._geomPart = "";
	this.options = options;
	
	
	this._vals = [];
	this._rows = [];
	this._cols = [];
	this._filters = [];
	this._solapContext = solap;
	//current request features for future drill/roll
	this._features = [];

	this.cubeName = "["+options.config2.Cubes[this._solapContext.curr_cube].name+"]";
	this._rowcard = 0;
	this._colcard = 0;
	this._filcard = 0;
	
	this.ordTree = null;
};

//Public functions


//getMDXQuery()
AtolCD.olap4js.MDXQuery.prototype.getQuery = function (feat) {

	this.setOrds();
	this.handleGeom(feat);
	this._regenQuery();
	return this.MDXQuery;
};

//Add a members to the request
AtolCD.olap4js.MDXQuery.prototype.addVal = function (node) {
	this._vals[node._0] = node;

};

//remove a member from this request
AtolCD.olap4js.MDXQuery.prototype.remVal = function (node) {
	delete this._vals[node._0];

};

//Add a members to the rows
AtolCD.olap4js.MDXQuery.prototype.addRows = function (node,ord) {
	if(!this._rows[ord]){
		this._rows[ord] = [];
	}
	this._rows[ord][this._rowcard] = node.id;
	this._rowcard++;
};

//Add a members to the cols
AtolCD.olap4js.MDXQuery.prototype.addCols = function (node,ord) {
	if(!this._cols[ord]){
		this._cols[ord] = [];
	}
	this._cols[ord][this._colcard] = node.id;
	this._colcard++;
};

//Add a members to the filter
AtolCD.olap4js.MDXQuery.prototype.addFilter = function (node,ord) {
	if(!this._filters[ord]){
		this._filters[ord] = [];
	}
	this._filters[ord][this._filcard] = node;
	this._filcard++;
};

// Getters/Setters
AtolCD.olap4js.MDXQuery.prototype.setOrds = function (ordTreeMod) {
	
	this._resetQuery();
	var that = this;
	this.ordTree = ordTreeMod;
	var order = 0;

	//pour chaque dim 
	for(var i in this.options.config2.Cubes[this._solapContext.curr_cube].Dimensions){
		this._filcard=0;
		for(var j in this._vals){
			if(this._vals[j].dim.toString() == "["+this.options.config2.Cubes[this._solapContext.curr_cube].Dimensions[i].name.toString()+"]"){
				this.addFilter(this._vals[j],order);
			}
		}
		order++;
	}
	
	this._regenQuery();	
};

AtolCD.olap4js.MDXQuery.prototype.getQueryObj = function () {
that = this;
return that;

};

//Hadle geometry params
AtolCD.olap4js.MDXQuery.prototype.handleGeom = function (selectedFeatures) {

	//Store this request features
	if(selectedFeatures.length>0){
		this._features = selectedFeatures;

	var geom_part = "NON EMPTY ";

		if(selectedFeatures.length==1){//OK
			geom_part+="{"+selectedFeatures[0].attributes.uniqueName+"}";
		}
		else if(selectedFeatures.length>=2){//We need to do an union
			for(var j in selectedFeatures){
				if(j<selectedFeatures.length-1){
					geom_part+="Union({"+selectedFeatures[j].attributes.uniqueName+"},";
					par+=")";
				}
				else{
					geom_part+="{"+selectedFeatures[j].attributes.uniqueName+"}";
				}		
			}
			geom_part+=par;
		}

	geom_part+="";
	
	//Replace default hierarchy w/ the selected one if diff
	
	this._geomPart = geom_part
	}
};


//Private Functions

AtolCD.olap4js.MDXQuery.prototype._resetQuery = function(){

	this._rows = [];
	this._cols = [];
	
	this._rowcard = 0;
	this._colcard = 0;
	this._filcard = 0;
	
	this.ordTree = null;

};

AtolCD.olap4js.MDXQuery.prototype._regenQuery = function(){
	
	var more_rows = false;
	var head = "";
	var queue = "";
	var request = " SELECT ";
	par = "";
	request+=this._geomPart;

	if(this._filters){
	
		head+="WITH";
		queue+=" WHERE (";
		for(var i in this._filters){//each dimension used on rows

			var curr_dim = this._filters[i][0].dim.toString();
	
			head+=" MEMBER "+curr_dim+".[Aggreg] AS 'Aggregate({";
			
			
			if(this._filters[i].length==1){//OK
				head+=this._filters[i][0].id.toString()+"})'";
			}
			else if(this._filters[i].length>=2)
				for(var j in this._filters[i]){
					if(j<this._filters[i].length-1){
						head+=this._filters[i][j].id.toString()+",";
					}
					else{
						head+=this._filters[i][j].id.toString()+"})'";
					}		
				}
			
			if(queue.charAt(queue.length-1)!="("){
				queue+=",";
			}
			queue+=curr_dim+".[Aggreg]";
		}
		
		queue+=")";
	}

	request+=" ON ROWS, AddCalculatedMembers([Measures].Members) ON COLUMNS FROM "+this.cubeName;
	
	head = head.replace(/'/g,"''''");
	head = head.replace(/'''Aggregate/g,"Aggregate");
	head = head.replace(/\)'''/g,")");
	

	
	this._head = head;
	this._queue = queue;
	
	request = head+request+queue;
	this.MDXQuery = request;

};

/**
*
 * 
 * @param {String} geoMember Unique Name of the Geographique composed member
 * @param {String} olapNavOp String describing the olap opeartion to be used (drill down || roll up)
 *
 * @return {String} MDX request to be executed
 */
AtolCD.olap4js.MDXQuery.prototype.olapNav = function(geoMember, olapNavOp){

	var tmpRequest = "SELECT ";
	
	//Make the olap nav op
	if(olapNavOp==0){
		this._geomPart = geoMember+".Children";
	}
	else if(olapNavOp==1){
		this._geomPart = geoMember+".Parent.Siblings";
	}

	tmpRequest+="NON EMPTY "+this._geomPart;
	tmpRequest+=" ON ROWS, AddCalculatedMembers([Measures].Members) ON COLUMNS FROM "+this.cubeName;
	tmpRequest = this._head+tmpRequest+this._queue;
	this.MDXQuery = tmpRequest;
	
	return tmpRequest;
};